//
//  UAVClientViewController.m
//  UAVClient
//
//  Created by visu4l on 11. 6. 29..
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "UAVClientViewController.h"

@implementation UAVClientViewController

@synthesize locationSensor;
@synthesize motionSensor;
@synthesize sensorModel;

@synthesize controller;
@synthesize imagePickerController;

@synthesize btnConnect;
@synthesize textStatus;
@synthesize compassImg;
@synthesize pictureView;

@synthesize textLat;
@synthesize textLng;
@synthesize textAlt;
@synthesize textHeading;
@synthesize textLocationAcc;
@synthesize textAltAcc;
@synthesize textSpeed;

@synthesize textRoll;
@synthesize textPitch;
@synthesize textYaw;


//video
@synthesize captureSession;
@synthesize imageView;
@synthesize customLayer;
@synthesize prevLayer;


//app start
-(void) viewDidLoad{
    
    [self printStatus:@"Start application"];
    
    [btnConnect setEnabled:false];
    
    if([self isNetworkReachable]){
        [self printStatus:@"connected WIFI"];
        [btnConnect setEnabled:true];
//        [self setup];
        
    }else{
        [self printStatus:@"Please, connect to WIFI"];
    }
    
    
    /* test
     */
    [self setup];
}

-(void) setup{
    
    //model
    sensorModel = [SensorModel alloc];

    //locaion manager
    locationSensor = [[LocationSensor alloc] init];
    
    //motion manager
    motionSensor = [[MotionSensor alloc] init];
    
    updateModelTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/20.0 target:self selector:@selector(updateModel) userInfo:nil repeats:YES];
    
    //init picker
    imagePickerController = [[UIImagePickerController alloc] init];
    imagePickerController.allowsEditing = NO;
    imagePickerController.delegate = self;
    imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
    
    
    //video init
    [self initCapture];
}


/**
 * network check
 * run on wifi
 */
-(Boolean) isNetworkReachable 
{
    struct sockaddr_in zeroAddr;
    bzero(&zeroAddr, sizeof(zeroAddr));
    zeroAddr.sin_len = sizeof(zeroAddr);
    zeroAddr.sin_family = AF_INET;
	
    SCNetworkReachabilityRef target = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddr);
	
    SCNetworkReachabilityFlags flag;
    SCNetworkReachabilityGetFlags(target, &flag);
	
    if(flag & kSCNetworkFlagsReachable){  // connected network. but, don't know network. 3g or wifi
        if(flag & kSCNetworkReachabilityFlagsIsWWAN){ 
            return false; //3g
        }else {
            return true;  //wifi
        }
    }else {
        return false;  // not connected any network
    }
}

-(void) updateModel{
    // model data update
    sensorModel.heading = locationSensor.heading;
    sensorModel.latitude = locationSensor.latitude;
    sensorModel.longitude = locationSensor.longitude;
    sensorModel.altitude =locationSensor.altitude;
    sensorModel.gspeed = locationSensor.speed;
    
    sensorModel.roll = motionSensor.roll;
    sensorModel.pitch = motionSensor.pitch;
    sensorModel.yaw = motionSensor.yaw;
    
    
    // UI contents update;
    textRoll.text =  [NSString stringWithFormat:@"%d", sensorModel.roll];
    textPitch.text = [NSString stringWithFormat:@"%d", sensorModel.pitch];
    textYaw.text =   [NSString stringWithFormat:@"%d", sensorModel.yaw];
    
    textLat.text = [NSString stringWithFormat:@"%ld", sensorModel.latitude];
    textLng.text = [NSString stringWithFormat:@"%ld", sensorModel.longitude];
    textAlt.text = [NSString stringWithFormat:@"%d", sensorModel.altitude];
    textHeading.text = [NSString stringWithFormat:@"%d", sensorModel.heading];
    
    textLocationAcc.text = [NSString stringWithFormat:@"%f", locationSensor.locationAcc];
    textAltAcc.text = [NSString stringWithFormat:@"%f", locationSensor.altitudeAcc];
    textSpeed.text = [NSString stringWithFormat:@"%d", sensorModel.gspeed];
    
    CGFloat angle = sensorModel.heading*(M_PI/180); 
    compassImg.transform = CGAffineTransformMakeRotation(-angle);
    [UIView commitAnimations];
}


-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo{

    pictureView.image = image;
    [[picker parentViewController] dismissModalViewControllerAnimated:YES ];

}

-(void) imagePickerControllerDidCancel:(UIImagePickerController *)picker{
    [picker dismissModalViewControllerAnimated:YES];
    
    NSLog(@"dismiss");
}

/*
 * click Connect button
 * 
 */

-(IBAction) clickPicture:(id)sender{
    
    [self presentModalViewController:self.imagePickerController animated:YES];
}

-(IBAction) clickConnect:(id)sender{
    
    controller = [[NetworkController alloc] init];
    
    // TODO : call createSock by thead
//    [control/ler performSelectorOnMainThread:@selector(createSock) withObject:<#(id)#> waitUntilDone:NO];
    
    if([controller createSock]){
        [btnConnect setEnabled:false];
        [self printStatus:@"OK. Connect to Server!"]; 
    }else{
        [self printStatus:@"check network. and Retry connect"]; 
    }
    
}

-(IBAction) clickSend:(id)sender{
    
    [self makeSendPacket];
}

-(void) makeSendPacket{
    struct SendData *data = (struct SendData*) malloc(sizeof(struct SendData));
    
    //TODO : modify flag and speed...
    
    data->State_Flag = 'c';
    data->latitude = sensorModel.latitude;
    data->longitude = sensorModel.longitude;
    data->gspeed = 0;
    data->heading = sensorModel.heading;
    data->roll = sensorModel.roll;
    data->pitch = sensorModel.pitch;
    data->yaw = sensorModel.yaw;
    data->msl = sensorModel.altitude;
    
    //TODO : make send data
    [controller sendPacket:data];

}


/*
 * video capture
 *
 */

-(void) initCapture{
    
    AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] error:nil];
    
    AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init];
    captureOutput.alwaysDiscardsLateVideoFrames = YES;
    
    dispatch_queue_t queue;
    queue = dispatch_queue_create("cameraQueue", NULL);
    [captureOutput setSampleBufferDelegate:self queue:queue];
    dispatch_release(queue);
    
    NSString *key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
    NSNumber *value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
    NSDictionary *videoSettings = [NSDictionary dictionaryWithObject:value forKey:key];
    [captureOutput setVideoSettings:videoSettings];
    
    self.captureSession = [[AVCaptureSession alloc] init];
    [self.captureSession addInput:captureInput];
    [self.captureSession addOutput:captureOutput];
    
    self.customLayer = [CALayer layer];
    self.customLayer.frame = self.view.bounds;
    self.customLayer.transform = CATransform3DRotate(CATransform3DIdentity, M_PI/2.0f, 0, 0, 1);
    self.customLayer.contentsGravity = kCAGravityResizeAspectFill;
    [self.view.layer addSublayer:self.customLayer];
    
    self.imageView = [[UIImageView alloc] init];
    self.imageView.frame = CGRectMake(500, 400, 400, 300);
    [self.view addSubview:self.imageView];
    
    self.prevLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
    self.prevLayer.frame = CGRectMake(400, 100, 300, 200);
    [self.view.layer addSublayer:self.prevLayer];

    [self.captureSession startRunning];
    
}

-(void) captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{
    
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(imageBuffer, 0);
    
    uint8_t *baseAddress = (uint8_t*)CVPixelBufferGetBaseAddress(imageBuffer);
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
    size_t width = CVPixelBufferGetWidth(imageBuffer);
    size_t height = CVPixelBufferGetHeight(imageBuffer);
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little|kCGImageAlphaPremultipliedFirst);
    CGImageRef newImage = CGBitmapContextCreateImage(newContext);
    
    CGContextRelease(newContext);
    CGColorSpaceRelease(colorSpace);
    
    [self.customLayer performSelectorOnMainThread:@selector(setContents:) withObject:nil waitUntilDone:YES];
    UIImage *image = [UIImage imageWithCGImage:newImage scale:1.0 orientation:UIImageOrientationRight];
    
    CGImageRelease(newImage);
    
    [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];
    
    CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
    
    [pool drain];
}




//
// util functions...
//

-(void) printStatus:(NSString *)msg{
    textStatus.text = [NSString stringWithFormat:@"%@ \n%@", textStatus.text, msg];
}


- (void)dealloc
{   [captureSession release];
    [imagePickerController release];

    [motionSensor release];
    [LocationSensor release];
    [sensorModel release];
    
    [controller release];
    
    [super dealloc];
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}


//#pragma mark - View lifecycle



- (void)viewDidUnload
{
    self.imageView = nil;
	self.customLayer = nil;
	self.prevLayer = nil;
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // return YES;
    // UI fix to Protrait
    return (interfaceOrientation >= UIInterfaceOrientationLandscapeLeft);
}

@end
